package day15.OneStageSystem;

import java.io.*;
import java.net.Socket;
import java.util.*;

public class Test {
    //定义用户存储列表<卡号,卡对象>
    static Map<String,MobileCard> card = new HashMap<>();
    //定义卡消费列表<卡号,消费记录>
    static Map<String, List<ConsumerInfo>> consumerInfos = new HashMap<>();
    //定义消费场景集合
    static List<Scene> scenes = new ArrayList<>();
    static {
        scenes.add(new Scene("通话",70,"问候客户,谁知客户如此难缠,通话70分钟"));
        scenes.add(new Scene("短信",30,"和朋友吐槽工作,十分尽兴,短信30条"));
        scenes.add(new Scene("流量",200,"由于工作需要,下载一个新的软件,流量消耗200MB"));
        scenes.add(new Scene("通话",100,"和父母通话聊天,问候身体和近况,通话100分钟"));
        scenes.add(new Scene("短信",15,"和同事询问工作上的事宜,短信15条"));
        scenes.add(new Scene("流量",400,"下班时间刷短视频,流量消耗400MB"));
        cardInput();
        consumerInput();
        phoneInput();
    }
    //定义已经被选择的号码
    static Set<String> selectedPhones = new HashSet<>();
    static Scanner sc = new Scanner(System.in);
    public static void main(String[] args) {
        menuOne();
        System.out.println("***谢谢使用***");
    }
    //一级菜单目录
    public static void menuOne(){
        sc.nextLine();
        while (true){
            System.out.println("***欢迎使用兜兜5G移动业务系统***");
            System.out.println("1.用户注册 2.用户登录 3.使用兜兜5G 4.话费充值 5.资费说明 6.退出系统");
            System.out.println("请输入您需要办理的业务:(1-6)");
            String choice = sc.nextLine();
            switch (choice){
                case "1":reg();break;
                case "2":login();break;
                case "3":use5G();break;
                case "4":addMoney();break;
                case "5":getPackageMessage();break;
                case "6":return;
                default:
                    System.out.println("请输入正确的选择!");
                    break;
            }
        }
    }
    //注册功能
    public static void reg(){
        System.out.println("以下是可挑选的电话号码：");
        String[] phones = getPhones();
        for (int i = 0; i < phones.length; i++) {
            System.out.print((i+1)+"."+phones[i]+" ");
            if ((i+1)%3 == 0) System.out.println();
        }
        String cardNumber = "";
        while (true) {
            System.out.println("请选择您中意的电话号码:(1-9) esc取消注册");
            String choice = sc.nextLine();
            boolean b = false;
            switch (choice){
                case "1":
                case "2":
                case "3":
                case "4":
                case "5":
                case "6":
                case "7":
                case "8":
                case "9":
                    cardNumber = phones[Integer.valueOf(choice) - 1];
                    selectedPhones.add(phones[Integer.valueOf(choice) - 1]);
                    b = true;
                    break;
                case "esc":return;
                default:
                    System.out.println("请输入正确的编号!");
                    break;
            }
            if (b) break;
        }
        ServicePackage servicePackage = null;
        while (true) {
            System.out.println("请选择套餐:1.话痨套餐 2.网虫套餐 3.超人套餐");
            System.out.println("请输入您的选择：(1-3) esc取消注册");
            String index = sc.nextLine();
            boolean b = false;
            switch (index){
                case "1":
                    servicePackage = new TalkPackage(58);
                    b = true;
                    break;
                case "2":
                    servicePackage = new NetPackage(68);
                    b = true;
                    break;
                case "3":
                    servicePackage = new SuperPackage(78);
                    b = true;
                    break;
                case "esc":return;
                default:
                    System.out.println("请输入正确的编号");
                    break;
            }
            if (b) break;
        }
        System.out.println("请输入您的用户名: (输入esc取消注册)");
        String username = sc.nextLine();
        if (username.equals("esc")) return;
        System.out.println("请输入您的密码：(输入esc取消注册)");
        String password = sc.nextLine();
        if (password.equals("esc")) return;
        double consumerAmount = 0;
        while (true) {
            System.out.println("请输入预存储的金额:");
            try {
                consumerAmount = sc.nextDouble();
                if (consumerAmount>=servicePackage.price){
                    break;
                }else {
                    System.out.println("当前预存储的金额不足以支付本月固定套餐费用！");
                }
            } catch (Exception e) {
                System.out.println("请输入正确的金额!");
            }
        }
        System.out.println("正在为您注册,请稍等.....");
        selectedPhones.add(cardNumber);
        MobileCard mobileCard = new MobileCard(cardNumber,username,password,servicePackage,
                servicePackage.price,(consumerAmount-servicePackage.price));
        card.put(cardNumber,mobileCard);
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        cardOutput();
        phoneOutput();
        System.out.println("注册成功!卡号:"+cardNumber+",用户名:"+username+",当前余额:"+mobileCard.getMoney());
        servicePackage.showInfo();
        sc.nextLine();
    }
    //随机9个电话号码
    public static String[] getPhones(){
        Set<String> set = new HashSet<>();
        Random r = new Random();
        while (set.size()<9){
            String phone = "139";
            for (int i = 0; i < 8; i++) {
                int number = r.nextInt(10);
                phone+=number;
            }
            boolean b = false;
            for (String s : selectedPhones){
                if (s.equals(phone)) b = true;
            }
            if (!b) set.add(phone);
        }
        return set.toArray(new String[0]);
    }
    //IO流获取套餐
    public static void getPackageMessage(){
        try(
            BufferedReader br = new BufferedReader(new InputStreamReader
                    (new FileInputStream("d://OneStageSystem//资费说明.txt")))
        ){
            String msg;
            while ((msg = br.readLine())!=null){
                System.out.println(msg);
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    //登录功能
    public static void login(){
        sc.nextLine();
        System.out.println("请输入电话号码:");
        String phone = sc.next();
        System.out.println("请输入密码:");
        String password = sc.next();
        boolean b = false;
        for (String s:Test.card.keySet()){
            if (s.equals(phone)&&card.get(s).getPassword().equals(password)){
                b = true;
                System.out.println(phone+"用户"+card.get(s).getUserName()+"欢迎您!");
                menuTwo(card.get(s));
            }
        }
        if (!b) System.out.println("用户不存在或用户名、密码错误");
    }
    //二级菜单
    public static void menuTwo(MobileCard mobileCard){
        while (true){
            System.out.println("*****兜兜5G移动用户菜单*****");
            System.out.println("1.本月账单查询");
            System.out.println("2.套餐余量查询");
            System.out.println("3.打印消费账单");
            System.out.println("4.套餐变更");
            System.out.println("5.办理退网");
            System.out.println("6.咨询客服");
            System.out.println("7.返回上一级");
            System.out.println("*****************************");
            System.out.println("请输入需要办理的业务:(1-7)");
            String choice = sc.next();
            switch (choice){
                case "1":showMonthBill(mobileCard);break;
                case "2":showBillResidue(mobileCard);break;
                case "3":printConsumption(mobileCard);break;
                case "4":changePackage(mobileCard);break;
                case "5":
                    CardServer.map.remove(mobileCard.getCardNumber());
                    quitNet(mobileCard);return;
                case "6":
                    try {
                        Socket client = new Socket("localhost",9999);
                        CardThread ct = new CardThread(client);
                        ct.start();
                        chat(mobileCard,client);
                    }catch (Exception e){}
                    break;
                case "7":return;
                default:
                    System.out.println("请输入正确的编号!");
                    break;
            }
        }
    }
    //使用兜兜5G
    public static void use5G(){
        Random r = new Random();
        System.out.println("请输入电话号码：");
        String phone = sc.next();
        MobileCard mobileCard = null;
        if (card.containsKey(phone)){
            mobileCard = card.get(phone);
        }else {
            System.out.println("电话号码为空号!");
            return;
        }
        while (true){
            System.out.println("*****"+mobileCard.getCardNumber()+"正在使用兜兜5G(输入任意键)*****");
            System.out.println("*****esc退出*****");
            String flag = sc.next();
            if (flag.equals("esc")) break;
            int index = r.nextInt(scenes.size());
            System.out.println(scenes.get(index).getDescription());
            String type = scenes.get(index).getType();
            double data = scenes.get(index).getData();
            if (type.equals("通话")) mobileCard.getServicePackage().call((int) data,mobileCard);
            else if (type.equals("流量")) mobileCard.getServicePackage().netPlay((int) data,mobileCard);
            else mobileCard.getServicePackage().send((int) data,mobileCard);
            ConsumerInfo consumerInfo = new ConsumerInfo(mobileCard.getCardNumber(),
                    scenes.get(index).getType(), scenes.get(index).getData());
            if (consumerInfos.containsKey(mobileCard.getCardNumber())){
                consumerInfos.get(mobileCard.getCardNumber()).add(consumerInfo);
            }else {
                List<ConsumerInfo> list = new ArrayList<>();
                list.add(consumerInfo);
                consumerInfos.put(mobileCard.getCardNumber(),list);
            }
            consumerOutput();
        }
    }
    //话费充值
    public static void addMoney(){
        System.out.println("请输入电话号码：");
        String phone = sc.next();
        MobileCard mobileCard = null;
        if (card.containsKey(phone)){
            mobileCard = card.get(phone);
        }else {
            System.out.println("电话号码为空号!");
            return;
        }
        while (true){
            System.out.println("请输入需要充值的金额:");
            double money = 0;
            try {
                money = sc.nextDouble();
                if (money>= 50){
                    mobileCard.setMoney(mobileCard.getMoney()+money);
                    System.out.println("话费充值成功!当前余额:"+mobileCard.getMoney());
                    break;
                }else {
                    System.out.println("请至少充值50元!");
                }
            } catch (Exception e) {
                System.out.println("请输入正确的金额!");
                sc.nextLine();
            }
            cardOutput();
        }
    }
    //本月账单查询
    public static void showMonthBill(MobileCard mobileCard){
        System.out.println("*****本月账单查询*****");
        System.out.println("您的卡号"+mobileCard.getCardNumber()+",当月账单:");
        System.out.println("套餐资费:"+mobileCard.getServicePackage().price+"元");
        System.out.println("合计:"+mobileCard.getConsumerAmount()+"元");
        System.out.println("账户余额:"+mobileCard.getMoney());
    }
    //套餐余量查询
    public static void showBillResidue(MobileCard mobileCard){
        System.out.println("*****套餐余量查询*****");
        System.out.println("您的卡号是"+mobileCard.getCardNumber()+",套餐内剩余:");
        double price = mobileCard.getServicePackage().price;
        if (price == 58){
            System.out.println("通话时长:"+Math.max((500-mobileCard.getRealTalkTime()),0)+"分钟");
            System.out.println("短信条数:"+Math.max((30-mobileCard.getRealSMSCount()),0)+"条");
            System.out.println("上网流量:"+0+"MB");
        }else if (price == 68){
            System.out.println("通话时长:"+0+"分钟");
            System.out.println("短信条数:"+0+"条");
            System.out.println("上网流量:"+Math.max((3*1024)- mobileCard.getRealFlow(),0)+"MB");
        }else {
            System.out.println("通话时长:"+Math.max((200-mobileCard.getRealTalkTime()),0)+"分钟");
            System.out.println("短信条数:"+Math.max((50-mobileCard.getRealSMSCount()),0)+"条");
            System.out.println("上网流量:"+Math.max(1024- mobileCard.getRealFlow(),0)+"MB");
        }
    }
    //打印消费
    public static void printConsumption(MobileCard mobileCard){
        String phone = mobileCard.getCardNumber();
        try(
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d://OneStageSystem//"+phone+"print.txt"));
        ){
            bos.write(("*****"+phone+"消费记录*****\n").getBytes());
            bos.write(("序号\t类型\t数据(通话(分钟)/上网(MB)/短信(条)\t\n").getBytes());
            for (String s:consumerInfos.keySet()){
                if (consumerInfos.get(s).isEmpty()){
                    bos.write(("暂无消费信息！\n").getBytes());
                    break;
                }
                if (s.equals(phone)){
                    List<ConsumerInfo> list = consumerInfos.get(s);
                    for (int i = 0; i < list.size(); i++) {
                        bos.write(((i+1)+"\t"+list.get(i).getType()+"\t"+list.get(i).getConsumerData()+"\n").getBytes());
                    }
                }
            }
            System.out.println("已经写入本地文件!");
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    //套餐变更
    public static void changePackage(MobileCard mobileCard){
        sc.nextLine();
        System.out.println("*****套餐变更*****");
        System.out.println("1.话痨套餐 2.网虫套餐 3.超人套餐");
        System.out.println("请输入需要变更的套餐的序号:");
        String index = sc.nextLine();
        switch (index){
            case "1":
                if (mobileCard.getServicePackage().price == 58){
                    System.out.println("对不起,您已经是该套餐用户,无需更换套餐!");
                }else {
                    if ((mobileCard.getMoney()-58)>0) {
                        ServicePackage newPack = new SuperPackage(58);
                        mobileCard.setServicePackage(newPack);
                        mobileCard.setConsumerAmount(mobileCard.getConsumerAmount()+newPack.price);
                        mobileCard.setMoney(mobileCard.getMoney()-newPack.price);
                        mobileCard.setRealTalkTime(0);
                        mobileCard.setRealSMSCount(0);
                        mobileCard.setRealFlow(0);
                        card.put(mobileCard.getCardNumber(),mobileCard);
                        cardOutput();
                        System.out.println("正在为卡号"+mobileCard.getCardNumber()+"办理更换套餐,请稍等...");
                        try {
                            Thread.sleep(1500);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("套餐更换完毕!");
                    }else {
                        System.out.println("对不起,当前用户余额不支持切换套餐!请先充值!");
                    }
                }
                break;
            case "2":
                if (mobileCard.getServicePackage().price == 68){
                    System.out.println("对不起,您已经是该套餐用户,无需更换套餐!");
                }else {
                    if ((mobileCard.getMoney()-68)>0) {
                        ServicePackage newPack = new SuperPackage(68);
                        mobileCard.setServicePackage(newPack);
                        mobileCard.setConsumerAmount(mobileCard.getConsumerAmount()+newPack.price);
                        mobileCard.setMoney(mobileCard.getMoney()- newPack.price);
                        mobileCard.setRealTalkTime(0);
                        mobileCard.setRealSMSCount(0);
                        mobileCard.setRealFlow(0);
                        card.put(mobileCard.getCardNumber(),mobileCard);
                        cardOutput();
                        System.out.println("正在为卡号"+mobileCard.getCardNumber()+"办理更换套餐,请稍等...");
                        try {
                            Thread.sleep(1500);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("套餐更换完毕!");
                    }else {
                        System.out.println("对不起,当前用户余额不支持切换套餐!请先充值!");
                    }
                }
                break;
            case "3":
                if (mobileCard.getServicePackage().price == 78){
                    System.out.println("对不起,您已经是该套餐用户,无需更换套餐!");
                }else {
                    if ((mobileCard.getMoney()-78)>0) {
                        ServicePackage newPack = new SuperPackage(78);
                        mobileCard.setServicePackage(newPack);
                        mobileCard.setConsumerAmount(mobileCard.getConsumerAmount()+newPack.price);
                        mobileCard.setMoney(mobileCard.getMoney()- newPack.price);
                        mobileCard.setRealTalkTime(0);
                        mobileCard.setRealSMSCount(0);
                        mobileCard.setRealFlow(0);
                        card.put(mobileCard.getCardNumber(),mobileCard);
                        cardOutput();
                        System.out.println("正在为卡号"+mobileCard.getCardNumber()+"办理更换套餐,请稍等...");
                        try {
                            Thread.sleep(1500);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("套餐更换完毕!");
                    }else {
                        System.out.println("对不起,当前用户余额不支持切换套餐!请先充值!");
                    }
                }
                break;
            default:
                System.out.println("请输入正确的编号");
                break;
        }
    }
    //办理退网
    public static void quitNet(MobileCard mobileCard){
        System.out.println("*****办理退网*****");
        String phone = mobileCard.getCardNumber();
        card.remove(phone);
        consumerInfos.remove(phone);
        selectedPhones.remove(phone);
        File f = new File("d://OneStageSystem//"+phone+"print.txt");
        f.delete();
        System.out.println("正在办理卡号"+phone+"的退网,请稍等...");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        cardOutput();
        consumerOutput();
        phoneOutput();
        System.out.println("卡号"+phone+"办理退网成功!");
        System.out.println("谢谢使用!");
    }
    //序列化
    public static void cardOutput(){
        try(
            FileOutputStream cardFos = new FileOutputStream("d://OneStageSystem//cardMap.xxx");
            ObjectOutputStream cardOos = new ObjectOutputStream(cardFos);
        ){
            cardOos.writeObject(card);
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    public static void consumerOutput(){
        try (FileOutputStream conFos = new FileOutputStream("d://OneStageSystem//consumerInfos.xxx");
             ObjectOutputStream conOos = new ObjectOutputStream(conFos);
        ){
            conOos.writeObject(consumerInfos);
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    public static void phoneOutput(){
        try(
            FileOutputStream phoneFos = new FileOutputStream("d://OneStageSystem//selectPhones.xxx");
            ObjectOutputStream phoneOos = new ObjectOutputStream(phoneFos);
        ){
            phoneOos.writeObject(selectedPhones);
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    //反序列化
    public static void cardInput(){
        try(
            FileInputStream cardFis = new FileInputStream("d://OneStageSystem//cardMap.xxx");
            ObjectInputStream cardOis = new ObjectInputStream(cardFis);
        ){
            card =(Map<String, MobileCard>)cardOis.readObject();
        }catch (FileNotFoundException e){
            System.out.println("欢迎第一次使用!");
        }catch (IOException e){
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    public static void consumerInput(){
        try(
            FileInputStream conFis = new FileInputStream("d://OneStageSystem//consumerInfos.xxx");
            ObjectInputStream conOos = new ObjectInputStream(conFis);
        ){
           consumerInfos = (Map<String, List<ConsumerInfo>>) conOos.readObject();
        }catch (FileNotFoundException e){
            System.out.println("欢迎第一次使用");
        }catch (IOException e){
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    public static void phoneInput(){
        try(
            FileInputStream phoneFis = new FileInputStream("d://OneStageSystem//selectPhones.xxx");
            ObjectInputStream phoneOos = new ObjectInputStream(phoneFis);
        ){
            selectedPhones = (Set<String>) phoneOos.readObject();
        }catch (FileNotFoundException e){
            System.out.println("欢迎第一次使用");
        }catch (IOException e){
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    //咨询客服
    public static void chat(MobileCard mobileCard,Socket client){
        try (OutputStream os = client.getOutputStream();
             BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()))) {
            // 发送用户电话号码
            os.write((mobileCard.getCardNumber() + "\n").getBytes());
            os.flush();
            while (true) {
                System.out.println("请输入要发送给客服的消息（输入 'esc' 退出咨询）:");
                String msg = sc.next();
                if ("esc".equals(msg)) {
                    break;
                }
                os.write((mobileCard.getCardNumber() + ": " + msg + "\n").getBytes());
                os.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}